package com.laiketui.admin.store.service.dubbo.notie;

import com.laiketui.admin.store.api.notie.PublicNoticeService;
import com.laiketui.admin.store.service.dubbo.systems.SearchServiceImpl;
import com.laiketui.common.api.PubliceService;
import com.laiketui.common.api.admin.PublicAdminService;
import com.laiketui.common.mapper.*;
import com.laiketui.common.utils.tool.DateUtil;
import com.laiketui.common.utils.tool.cache.RedisDataTool;
import com.laiketui.common.utils.tool.str.StringUtils;
import com.laiketui.core.cache.RedisUtil;
import com.laiketui.core.common.SplitUtils;
import com.laiketui.core.exception.LaiKeAPIException;
import com.laiketui.core.lktconst.GloabConst;
import com.laiketui.core.utils.tool.DataUtils;
import com.laiketui.domain.lktconst.DictionaryConst;
import com.laiketui.domain.lktconst.ErrorCode;
import com.laiketui.domain.log.AdminRecordModel;
import com.laiketui.domain.mch.AdminModel;
import com.laiketui.domain.mch.CustomerModel;
import com.laiketui.domain.message.MessageLoggingModal;
import com.laiketui.domain.order.OrderModel;
import com.laiketui.domain.systems.SystemTellModel;
import com.laiketui.domain.systems.SystemTellStoreModel;
import com.laiketui.domain.vo.MainVo;
import com.laiketui.domain.vo.systems.AddNoticeVo;
import org.apache.commons.collections.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 公告管理
 *
 * @author Trick
 * @date 2021/1/19 15:44
 */
@Service
public class PublicNoticeServiceImpl implements PublicNoticeService {
    private final Logger logger = LoggerFactory.getLogger(SearchServiceImpl.class);

    @Override
    public Map<String, Object> getPublicNoticeInfo(MainVo vo, Integer id, Integer isStore) throws LaiKeAPIException {
        Map<String, Object> resultMap = new HashMap<>(16);
        try {
            Map<String, Object> parmaMap = new HashMap<>(16);
            //商户端获取商城公告，不展示该商场创建时间之前的公告  禅道 51552
            if (StringUtils.isNotEmpty(isStore) && isStore == 1){
                CustomerModel customerModel = customerModelMapper.selectByPrimaryKey(vo.getStoreId());
                if (customerModel == null){
                    throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_SJCW, "数据错误", "getPublicNoticeInfo");
                }
                parmaMap.put("storeTime", DateUtil.dateFormate(customerModel.getAdd_date(), GloabConst.TimePattern.YMDHMS));
            }
            parmaMap.put("store_id", 0);
            if (id != null && id > 0) {
                parmaMap.put("id", id);
            }
            parmaMap.put("add_time_sort", DataUtils.Sort.DESC.toString());
            parmaMap.put("pageStart", vo.getPageNo());
            parmaMap.put("pageEnd", vo.getPageSize());

            List<Map<String, Object>> systemTellModelList = systemTellModelMapper.selectDynamic(parmaMap);
            List<Integer> storeTypes;
            StringBuilder storeTypesName;
            int total = systemTellModelMapper.countDynamic(parmaMap);
            for (Map<String, Object> map : systemTellModelList) {
                storeTypes = new ArrayList<>();
                storeTypesName = new StringBuilder();
                int type = MapUtils.getIntValue(map, "type");
                int tellId = MapUtils.getIntValue(map, "id");
                String status;
                Date startDate = DateUtil.dateFormateToDate(MapUtils.getString(map, "startdate"), GloabConst.TimePattern.YMDHMS);
                Date endDate = DateUtil.dateFormateToDate(MapUtils.getString(map, "enddate"), GloabConst.TimePattern.YMDHMS);
                if (DateUtil.dateCompare(new Date(), endDate)) {
                    status = "已失效";
                } else if (DateUtil.dateCompare(startDate, new Date())) {
                    status = "未生效";
                } else {
                    status = "生效中";
                    //只有系统维护才踢人
                    if (type == 1) {
                        //获取所有商城
                        List<Integer> storeIdList = customerModelMapper.getStoreIdAll(new Date());
                        for (Integer storeId : storeIdList) {
                            publicAdminService.outLoginStoreAdminAll(storeId);
                        }
                    }
                }
                map.put("status", status);
                //判断商城是否查阅
                SystemTellStoreModel systemTellStoreModel = new SystemTellStoreModel();
                systemTellStoreModel.setStore_id(vo.getStoreId());
                systemTellStoreModel.setTell_id(tellId);
                systemTellStoreModel = systemTellStoreModelMapper.selectOne(systemTellStoreModel);
                if (systemTellStoreModel != null){
                    map.put("is_read", DictionaryConst.WhetherMaven.WHETHER_OK);
                }else {
                    map.put("is_read", DictionaryConst.WhetherMaven.WHETHER_NO);
                }
                for (int i = 0; i < 5; i++) {
                    switch (i){
                        case 0:
                            if (MapUtils.getInteger(map, "store_tell").equals(SystemTellModel.TELL.YES)) {
                                storeTypes.add(i);
                                storeTypesName.append("管理后台").append(SplitUtils.DH);
                            }
                            break;
                        case 1:
                            if (MapUtils.getInteger(map, "user_tell").equals(SystemTellModel.TELL.YES)) {
                                storeTypes.add(i);
                                storeTypesName.append("用户端").append(SplitUtils.DH);
                            }
                            break;
                        case 2:
                            if (MapUtils.getInteger(map, "mch_tell").equals(SystemTellModel.TELL.YES)) {
                                storeTypes.add(i);
                                storeTypesName.append("商家端").append(SplitUtils.DH);
                            }
                            break;
                        case 3:
                            if (MapUtils.getInteger(map, "supplier_tell").equals(SystemTellModel.TELL.YES)) {
                                storeTypes.add(i);
                                storeTypesName.append("供应商端").append(SplitUtils.DH);
                            }
                            break;
                        case 4:
                            if (MapUtils.getInteger(map, "mch_son_tell").equals(SystemTellModel.TELL.YES)) {
                                storeTypes.add(i);
                                storeTypesName.append("门店端").append(SplitUtils.DH);
                            }
                            break;
                    }
                }
                map.put("storeTypes", storeTypes);
                map.put("storeTypesName", StringUtils.trim(storeTypesName.toString(), SplitUtils.DH));
            }

            resultMap.put("list", systemTellModelList);
            resultMap.put("total", total);
        } catch (LaiKeAPIException l) {
            throw l;
        } catch (Exception e) {
            logger.error("获取系统公告 异常", e);
            throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_WLYC, "网络异常", "getPublicNoticeInfo");
        }
        return resultMap;
    }

    @Override
    public boolean addSysNoticeInfo(AddNoticeVo vo) throws LaiKeAPIException {
        try {
            AdminModel adminModel = RedisDataTool.getRedisAdminUserCache(vo.getAccessId(), redisUtil);
            int count;
            SystemTellModel systemTellModelOld = null;
            if (vo.getId() != null) {
                systemTellModelOld = systemTellModelMapper.selectByPrimaryKey(vo.getId());
                if (systemTellModelOld == null) {
                    throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_GGBCZ_001, "公告不存在");
                }
            }
            if (StringUtils.isEmpty(vo.getTitle())) {
                throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_BTBNWK, "标题不能为空");
            }
            if (vo.getType() == null) {
                throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_GGLXBNWK, "公告类型不能为空");
            }
            if (systemTellModelOld == null) {
                if (StringUtils.isEmpty(vo.getStartDate())) {
                    throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_KSSJBNWK, "开始时间不能为空");
                } else if (StringUtils.isEmpty(vo.getEndDate())) {
                    throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_JSSJBNWK, "结束时间不能为空");
                }
            }
            if (!DateUtil.dateCompare(vo.getStartDate(), DateUtil.dateFormate(new Date(), GloabConst.TimePattern.YMDHMS))) {
                throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_KSSJBNXYDQSJ, "开始时间不能小于当前时间");
            }
            if (!DateUtil.dateCompare(vo.getEndDate(), vo.getStartDate())) {
                throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_KSSJBNDYJSSJ, "开始时间必须小于结束时间");
            }
            if (StringUtils.isEmpty(vo.getContent())) {
                throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_GGNRBNWK, "公告内容不能为空");
            }
            if (StringUtils.isEmpty(vo.getStoreTypes())) {
                throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_JSFBNWK, "接收方不能为空");
            }
            String[] StoreTypeList = vo.getStoreTypes().split(SplitUtils.DH);
            SystemTellModel systemTellModelSave = new SystemTellModel();
            systemTellModelSave.setType(vo.getType());
            systemTellModelSave.setTitle(vo.getTitle());
            systemTellModelSave.setContent(vo.getContent());
            systemTellModelSave.setTimetype(vo.getIsTime());
            systemTellModelSave.setStartdate(vo.getStartDate());
            systemTellModelSave.setEnddate(vo.getEndDate());
            systemTellModelSave.setStoreTell(SystemTellModel.TELL.No);
            systemTellModelSave.setUserTell(SystemTellModel.TELL.No);
            systemTellModelSave.setMchTell(SystemTellModel.TELL.No);
            systemTellModelSave.setSupplierTell(SystemTellModel.TELL.No);
            systemTellModelSave.setMchSonTell(SystemTellModel.TELL.No);
            for (String s : StoreTypeList) {
                switch (s){
                    case "0":
                        systemTellModelSave.setStoreTell(SystemTellModel.TELL.YES);
                        break;
                    case "1":
                        systemTellModelSave.setUserTell(SystemTellModel.TELL.YES);
                        break;
                    case "2":
                        systemTellModelSave.setMchTell(SystemTellModel.TELL.YES);
                        break;
                    case "3":
                        systemTellModelSave.setSupplierTell(SystemTellModel.TELL.YES);
                        break;
                    case "4":
                        systemTellModelSave.setMchSonTell(SystemTellModel.TELL.YES);
                        break;
                }
            }
            //判断时间段中是否存在交集数据
            Date start = DateUtil.dateFormateToDate(vo.getStartDate(), GloabConst.TimePattern.YMDHMS);
            Date end = DateUtil.dateFormateToDate(vo.getEndDate(), GloabConst.TimePattern.YMDHMS);
            Map<String, Object> paramMap = new HashMap<>(16);
            paramMap.put("type", vo.getType());
//            paramMap.put("startDate", new Date());
            if (vo.getId() != null) {
                paramMap.put("idNot", vo.getId());
            }
            List<Map<String, Object>> mapList = systemTellModelMapper.selectDynamic(paramMap);
            if (mapList.size() > 0) {
                mapList.stream().forEach(map -> {
                    Date startDate = DateUtil.dateFormateToDate(MapUtils.getString(map, "startdate"), GloabConst.TimePattern.YMDHMS);
                    Date endDate = DateUtil.dateFormateToDate(MapUtils.getString(map, "enddate"), GloabConst.TimePattern.YMDHMS);
                    ;
                    boolean b = DateUtil.hasOverlap(start, end, startDate, endDate);
                    if (b) {
                        throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_GLXZGSJDZYCZSXDGG, "该类型在该时间段中已存在生效中的公告");
                    }
                });
            }
            if (systemTellModelOld != null) {
                systemTellModelSave.setId(systemTellModelOld.getId());
                count = systemTellModelMapper.updateByPrimaryKeySelective(systemTellModelSave);
                //添加操作日志
                publiceService.addAdminRecord(vo.getStoreId(),"修改了公告："+vo.getTitle()+"的信息" ,AdminRecordModel.Type.UPDATE, vo.getAccessId());
            } else {
                systemTellModelSave.setAdd_time(new Date());
                count = systemTellModelMapper.insertSelective(systemTellModelSave);
                //添加操作日志
                publiceService.addAdminRecord(vo.getStoreId(), "添加了公告："+vo.getTitle(),AdminRecordModel.Type.ADD, vo.getAccessId());
            }
            return count > 0;
        } catch (LaiKeAPIException l) {
            throw l;
        } catch (Exception e) {
            logger.error("获取系统公告 异常", e);
            throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_WLYC, "网络异常", "addSysNoticeInfo");
        }
    }

    @Override
    public boolean delSysNoticeInfo(String token,int storeId, Integer id) throws LaiKeAPIException {
        try {
            AdminModel adminModel = RedisDataTool.getRedisAdminUserCache(token, redisUtil);
            SystemTellModel systemTellModel = new SystemTellModel();
            systemTellModel.setId(id);
            systemTellModel = systemTellModelMapper.selectOne(systemTellModel);
            if (systemTellModel == null) {
                throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_XTGGBCZ, "系统公告不存在");
            }
            int count = systemTellModelMapper.deleteByPrimaryKey(id);
            //添加操作日志
            publiceService.addAdminRecord(storeId,"删除了公告："+systemTellModel.getTitle(),AdminRecordModel.Type.DEL,token);
            return count > 0;
        } catch (Exception e) {
            logger.error("删除系统公告 异常", e);
            throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_WLYC, "网络异常", "delSysNoticeInfo");
        }
    }

    @Override
    public Map<String, Object> noticeList(MainVo vo) throws LaiKeAPIException {
        Map<String, Object> resultMap = new HashMap<>(16);
        try {
            AdminModel user = RedisDataTool.getRedisAdminUserCache(vo.getAccessId(), redisUtil);
            //订单(待发货)、订单(售后)、订单(提醒发货)、订单(订单关闭)、订单(新订单)、订单(收货)
            int[] orderTypes = new int[]{1, 2, 3, 4, 5, 6};
            Map<String, Object> orderMap = new HashMap<>(16);
            // 商品(审核)、商品(补货)
            int[] goodsTypes = new int[]{7, 9};
            Map<String, Object> goodsMap = new HashMap<>(16);
            //账单通知 用户提现审核、店铺提现(审核)、供应商提现审核
            int[] checkTypes = new int[]{19, 20, 21};
            Map<String, Object> checkMap = new HashMap<>(16);
            //获取订单相关的通知
            noticeData(vo.getStoreId(), 0, orderTypes, orderMap);
            //获取商品相关的通知
            noticeData(vo.getStoreId(), 0, goodsTypes, goodsMap);
            //获取账单相关的通知
            noticeData(vo.getStoreId(), 0, checkTypes, checkMap);

            List<Map<String, Object>> resultList = new ArrayList<>();
            resultList.add(orderMap);
            resultList.add(goodsMap);
            resultList.add(checkMap);
            resultMap.put("list", resultList);
        } catch (LaiKeAPIException l) {
            throw l;
        } catch (Exception e) {
            logger.error("商城消息通知 异常", e);
            throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_WLYC, "网络异常", "noticeList");
        }
        return resultMap;
    }

    //通知消息结构辅助方法
    private void noticeData(int storeId, int mchId, int[] types, Map<String, Object> resultMap) throws LaiKeAPIException {
        try {
            Map<String, Object> map = new HashMap<>(16);
            //获取自营店id
            Integer storeMchId = customerModelMapper.getStoreMchId(storeId);
            map.put("store_id", storeId);
            if (mchId != 0) {
                map.put("mch_id", mchId);
            }
            map.put("read_or_not", 0);
            int totalMain = 0;
            List<Map<String, Object>> mainList = new ArrayList<>();
            //获取当前订单的通知
            for (int type : types) {
                map.put("type", type);
                int total = messageLoggingModalMapper.countDynamic(map);
                totalMain += total;
                List<Map<String, Object>> noticeList = messageLoggingModalMapper.selectDynamic(map);
                List<Map<String, Object>> noticeListTemp = new ArrayList<>();
                for (Map<String, Object> notice : noticeList) {
                    Map<String, Object> noticeMap = new HashMap<>(16);

                    if (MapUtils.getString(notice, "content").contains(DictionaryConst.OrdersType.ORDERS_HEADER_GM)){
                        //订单号
                        Integer orderId = MapUtils.getInteger(notice, "parameter");
                        OrderModel orderModel = new OrderModel();
                        orderModel.setId(orderId);
                        orderModel= orderModelMapper.selectOne(orderModel);
                        if(orderModel == null){
                            logger.debug("订单id:{}的订单不存在", orderId);
                        }else {
                            if (orderModel.getSelf_lifting() != null && orderModel.getSelf_lifting() == 1){
                                noticeMap.put("self_lifting", 1);
                            }else {
                                noticeMap.put("self_lifting", 0);
                            }
                        }
                    }else {
                        //插件订单只获取自营店的
                        if (storeMchId != null &&!storeMchId.equals(MapUtils.getInteger(notice, "mch_id")))
                            if (MapUtils.getString(notice, "content").contains("订单"))
                            continue;
                    }
                    noticeMap.put("id", MapUtils.getInteger(notice, "id"));
                    noticeMap.put("parameter", MapUtils.getString(notice, "parameter"));
                    noticeMap.put("toUrl", MapUtils.getString(notice, "to_url"));
                    noticeMap.put("content", MapUtils.getString(notice, "content"));
                    noticeMap.put("is_popup", MapUtils.getString(notice, "is_popup"));
                    noticeMap.put("add_date", DateUtil.dateFormate(MapUtils.getString(notice, "add_date"), GloabConst.TimePattern.YMDHMS));
                    noticeListTemp.add(noticeMap);
                }
                Map<String, Object> noticeMap = new HashMap<>(16);
                noticeMap.put("list", noticeListTemp);
                noticeMap.put("total", total);
                noticeMap.put("type", type);
                mainList.add(noticeMap);
            }
            resultMap.put("list", mainList);
            resultMap.put("total", totalMain);
            resultMap.put("type", Arrays.toString(types));
        } catch (LaiKeAPIException l) {
            throw l;
        } catch (Exception e) {
            logger.error("商城消息通知通知 异常", e);
            throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_WLYC, "网络异常", "noticeData");
        }
    }

    @Override
    public void noticeRead(MainVo vo, Integer id, String types) throws LaiKeAPIException {
        try {
            AdminModel user = RedisDataTool.getRedisAdminUserCache(vo.getAccessId(), redisUtil);
            String[] typeList = null;
            MessageLoggingModal messageLoggingModal = new MessageLoggingModal();
            messageLoggingModal.setStore_id(vo.getStoreId());
            messageLoggingModal.setRead_or_not(DictionaryConst.WhetherMaven.WHETHER_OK);
            if (id != null) {
                messageLoggingModal.setId(id);
                messageLoggingModalMapper.updateByPrimaryKeySelective(messageLoggingModal);
            }
            if (types != null) {
                typeList = types.split(SplitUtils.DH);
            }
            if (typeList != null) {
                for (String type : typeList) {
                    messageLoggingModal.setType(Integer.parseInt(type));
                    messageLoggingModalMapper.noticeRead(vo.getStoreId(), null, type);
                }
            }

        } catch (LaiKeAPIException l) {
            throw l;
        } catch (Exception e) {
            logger.error("标记消息已读 异常", e);
            throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_WLYC, "网络异常", "noticeRead");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void noticePopup(MainVo vo, String ids) throws LaiKeAPIException {
        try {
            AdminModel user = RedisDataTool.getRedisAdminUserCache(vo.getAccessId(), redisUtil);
            if (StringUtils.isEmpty(ids)) {
                throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_BNWK, "id不能为空");
            }
            String[] idList = ids.split(SplitUtils.DH);
            int count = messageLoggingModalMapper.updateMessLogPopup(idList);
            if (count < 1) {
                throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_CZSB, "操作失败");
            }

        } catch (LaiKeAPIException l) {
            throw l;
        } catch (Exception e) {
            logger.error("标记已弹窗 异常", e);
            throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_WLYC, "网络异常", "noticeRead");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void readSysNotice(MainVo vo, String ids) throws LaiKeAPIException {
        try {
            RedisDataTool.getRedisAdminUserCache(vo.getAccessId(), redisUtil);
            if (StringUtils.isEmpty(ids)) {
                throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_BNWK, "id不能为空");
            }
            String[] idList = ids.split(SplitUtils.DH);
            for (String id : idList){
                SystemTellStoreModel systemTellStoreModel = new SystemTellStoreModel();
                systemTellStoreModel.setStore_id(vo.getStoreId());
                systemTellStoreModel.setTell_id(Integer.valueOf(id));
                systemTellStoreModel = systemTellStoreModelMapper.selectOne(systemTellStoreModel);
                if (systemTellStoreModel == null){
                    SystemTellStoreModel save = new SystemTellStoreModel();
                    save.setStore_id(vo.getStoreId());
                    save.setTell_id(Integer.valueOf(id));
                    save.setAdd_time(new Date());
                    systemTellStoreModelMapper.insertSelective(save);
                }
            }
        } catch (LaiKeAPIException l) {
            throw l;
        } catch (Exception e) {
            logger.error("标记系统公告-已读 异常", e);
            throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_WLYC, "网络异常", "readSysNotice");
        }
    }

    @Autowired
    private SystemTellModelMapper systemTellModelMapper;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private MessageLoggingModalMapper messageLoggingModalMapper;

    @Autowired
    private PublicAdminService publicAdminService;

    @Autowired
    private CustomerModelMapper customerModelMapper;

    @Autowired
    private OrderModelMapper orderModelMapper;

    @Autowired
    private SystemTellStoreModelMapper systemTellStoreModelMapper;

    @Autowired
    private PubliceService publiceService;
}

